.TITLE TTLH .IDENT /04.03/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; Authors: BEN LEVIN 14-JUN-84 ; Tony Lekas ; ; Modified By: ; ; S. C. Adams 14-Jun-89 04.00 ; ; SA498 -- Report error on set/get speed, parity, and ; character length ; ; J. Mickalide 28-Jun-89 04.01 ; ; JEM001 -- Correct routine LHOUT to save space in buffer for data_b ; slot but not to move any data and to fill in a slot size ; of six in the header. ; ; D. Carroll 23-March-92 04.02 ; ; DTC001 -- Correct problem when using special echo from within an ; ACD in which the echo buffer is externally mapped, and does ; not reside within pool, the UCBX, or TTCOM. ; ; D. Carroll 22-Aug-1994 04.03 ; ; DC299 -- Correct DTC001 to only map external buffer when the ; output request is not buffered output ... (Instinet) ; ; ; Controller-Dependent routine for LH Device (LAT HOST) ; ; LH devices are considered to be remote terminals, connected through ; the LAT-multiplexer and are always setup in the data base as remote ; terminals. ; ; LH port data base structure: ; LH port belongs to a 'TT' device and has its own DCB (Generic device ; name is 'TT'). ; LH port data base has one contigious SCB/KRB. ; LH controller has a CTB, linked to CTB list ($CTLST) and has a ; generic controller name (L.NAM) 'LH' (LAT host). ; ; Calls: ; From port to process: ; The SCB/KRB block will contain two words with ; LAT process bias/virtual address. $MPPRO routine will ; map and call it. ; From process to port: ; The first address in the driver dispatch table for the ; LH controller will be used by LCP to set up the calling ; information for the LAT process. ; .IF DF T$$LTH ; ; UCB Extentions for LH devices ; ----------------------------- ; Status/control information ; U.LINS ; Link status ; U.CREN ; Transmit credits counter (low 4 bits) ; Link Status Extension (High 4 bits of U.CREN) ; Server/circuit identification ; U.SRVN ; Server number ; U.SESN ; Session number ; Parametrs on receive data ; U.RSBB ; Receive slot bias ; U.RBHA ; Receive slot header virtual ; U.RSDV ; Receive data virtual ; XMT intermediate buffer chain ; U.TRLH ; XMT listhead address ; U.TRSC ; XMT remained bytes in buffer ; U.SLSZ ; Maximum slot size on XMT ; Virtual circuit CCB ; U.CCBA ; CCB address (low core) ; ; Link Status Word U.LINS word in UCB ; ---------------- ;######################### ;modify UCBDF for these ; UL.TRS=1 ; 1-XMT stopped, 0-Not ; >255 Char. for slot. Hold it. ; UL.TDA=2 ; 1-XMT data avail, 0-Not ; Data in XMT queue (set by port) UL.XON=4 ; 1-Notify the process of an XON ; 0-Notify the process of output data ; UL.RDA=10 ; 1-RCV data avail, 0-Not ; Data in RCV queue (set by proc) UL.NTO=20 ; 1-Non task output pending, o-Not UL.NOD=40 ; 1-ODONE call defered because too much ; data was buffered, 0 - Not ; UL.RSS=100 ; 1-RCV stopped, 0-Not ; RCV stopped by TTDRV on receive ; if no resources available ; UL.LEN=200 ; 1-Link enable, 0-Not ; toggled by start/stop link call ; ; Link Statue Extension bits (High 4 bits of U.CREN) ; ;LE.HIP=20 ; hangup in progress ; set if LHMTIM is called by terminal ; driver before all available data ; has been sent to server. ; subsequent I/O will not complete until ; data has been sent, and bit is cleared ; ;LE.TDC=40 ; Transmit data completed ; Bit set during .HIP when the data ; has all been transmitted. ; ;LE.CIP=100 ; Connection in progress ; Bit set when a connection to a terminal ; server is pending. Set after output ; has been attempted to a Lat Application Term, ; but no connection has been established to ; the terminal server associated with the ; terminal. ; LE.ORG=200 ; Bit set by $LHSTS if connection result ; of IO.ORG (Explicit connection) ; ; ; ; Error Codes ; ----------- ; NOTE: Do not change there codes without checking LAT process module ; LATPRT. Some of there codes are common to both, and are not ; globaly defined. Adding a code will not cause a problem. ER$SUC=0 ; Sucess ER$MLE=-1 ; Maximum links exeeded ER$IDN=-2 ; Incorrect identifyer ER$SYN=-3 ; Synchronization error ER$UDC=-4 ; Undefined operation code ER$NDR=-5 ; No data ready for transmit ER$LND=-6 ; LH data base not loaded ER$NRR=-7 ; No receive data ready ER$OVR=-10 ; Data overrun occured ER$SIU=-11 ; Service In Use ER$PNU=-12 ; Port Name Unknown ER$SNO=-13 ; Service Not offered ; ; Process-to-Port Call Operation Codes ; ------------------------------------ PR$STS=0 ; Start session PR$RCV=2 ; Receive PR$XMT=4 ; Transmit PR$DSC=6 ; Stop session PR$GTD=10 ; Get transmit data for app. terminal PR$TMO=12 ; Connect request timed out in implicit connect ; ; Port-to-Process Operation Codes ; ------------------------------- PO$DSC=0 ; Stop session ("BYE" by task) ;PO$FLO=2 ; Flow control status change ;PO$HST=2 ; Host sync toggled ;PO$TST=4 ; Terminal sync toggeld PO$XON=6 ; XON ;PO$XOF=10 ; XOFF (possible data overrun) PO$ABO=12 ; Abort output PO$OUT=14 ; Start output PO$MSD==16 ; Mark a session for disconnect PO$CNT=20 ; initiate implicit connection from terminal ser PO$ORG==22 ; ininate connection from IO.ORG PO$GQD==24 ; Get QUEUE depth PO$MAP==26 ; Set/Get Mapping parameters ; ; LAT Message Header Offsets ; -------------------------- SL$SID=1 ; Slot ident SL$SBC=2 ; Slot byte count SL$TYP=3 ; Slot type SL$SDS=4 ; Slot data start ; ; Buffer type codes ; ----------------- BF$NOR=0 ; Normal data. Includes non task output. BF$RPR=1 ; IO.RPR Prompt string. BF$FLO=2 ; Flow control information. ; ; Maximum number of queued buffers ; -------------------------------- ; MAXBUF=4 ; ;+++ ; .MCALL DCBDF$,UCBDF$,CTBDF$,SCBDF$ .MCALL UCBDF$,CCBDF$ DCBDF$ ; Define DCB UCBDF$ ,,TTDEF ; Define UCB CTBDF$ ; Define CTB SCBDF$ ; Define SCB CCBDF$ ; Define CCB .PSECT MAP6 ; ; $LHGTD - Get transmit data from task, and start output. ; this is called by LAT process upon terminal server establishing ; connection to Lat Application Terminal during an IMPLICIT connection. ; Completion of I/O is delayed until connection is established and ; must be re-started.. ; ; Inputs: R5 - pointer to U.TSTA ; $LHGTD::MOV R1,R5 ; Point to U.TSTA CALL MUCBX ; Map the UCBX TST U.TCO(R4) ; Task output? BNE LHSTAX ; if so, fall through to start output. TSTB U.TOC(R4) ; Non-Task output? BNE LHSTAX ; if NE, yes - go do it. RETURN ; Else return - could be bad call.. ; ; ; LHSTAX - Start Output Entry Point ; ; Input: ; Registers R2-R5 are standard for controller-dependent routine ; ; R2 - Phisical unit number * 2 ; (only if multiplexers in system) ; ; R3 - CSR address (unused for LH device) ; R4 - UCBX address ; R5 - Pointer to U.TSTA ; ; ; LHSTAX:: CLRB U.TOTI(R4) ; LAT process deals with timers MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 ; BIT #S6.LAT,U.TST6-U.TSTA(R5) ; Lat Application Terminal? BEQ 7$ ; if EQ - no, normal output.. BITB #UL.LEN,U.LINS-U.TSTA(R5) ; link Enabled? BNE 7$ ; If NE - Yes, continue.. ; ; here, we have output, but no link is enabled on an application terminal ; We must call the LAT process, and try to establish the connection. ; BISB #LE.CIP,U.CREN-U.TSTA(R5) ; Show connection in progress BISB #US.DSB,U.STS-U.TSTA(R5) ; Toggle read/write so no more ; I/O is possible to this TT ; until connection completes MOV #PO$CNT,R3 ; show connect reason CALL LTPRC ; call LAT process.. MOV (SP)+,R2 ; Restore Registers MOV (SP)+,R1 ; And RETURN ; Return 7$: ; ; Buffer chain in U.TFOB ; Check high priority output BIT #S5.HPC,U.TST5-U.TSTA(R5) ; High priority output? BEQ OUTPUT ; Branch if not ; XON or XOF bits set. Let lat ; know and exit (no odone call!) BIT #S5.XOF,U.TST5-U.TSTA(R5) ; Output an XOFF? BEQ 10$ ; Branch if not BIC #S5.XOF,U.TST5-U.TSTA(R5) ; Yes-clear XOFF bit BISB #UL.RSS,U.LINS-U.TSTA(R5) ; RCV-STOPPED on link BR IODON ; All done for now ; ; Not XOFF, must be XON ; 10$: BIC #S5.XON,U.TST5-U.TSTA(R5) ; Clear XON bit BICB #UL.RSS,U.LINS-U.TSTA(R5) ; RCV-STOPPED cleared BISB #UL.XON,U.LINS-U.TSTA(R5) ; Set reason for fork BR DOFORK ; Jump to call process OUTPUT: ; Continue normal priority output BICB #UL.XON,U.LINS-U.TSTA(R5) ; Settup reason for fork TST U.TCO(R4) ; Task output? BNE 5$ ; If NE yes - go process it CALL PRNTO ; Process non task output BR DOFORK ; And exit 5$: MOV U.TRLH-U.TSTA(R5),R1 ; R1-XMT buffers chain starts BEQ 30$ ; Branch if there is no XMT chain 10$: TST (R1) ; There is an XMT chain- BEQ 20$ ; Find end of MOV (R1),R1 ; XMT BR 10$ ; Chain 20$: MOV U.TFOB(R4),(R1) ; Link new chain to XMT chain BR 50$ ; And go to stamp new chain 30$: MOV U.TFOB(R4),U.TRLH-U.TSTA(R5) ; No XMT chain-create it (link ; new buffers to xmt chain) ; Stamp all new chain with 0 ; In the left byte of the ; Second word-don't deallocate ; this buffer in LHOUT 50$: MOV U.TFOB(R4),R1 ; R1-first buffer in new chain MOV #BF$RPR,R3 ; Assume that this is a prompt BIT #S5.RPO,U.TST5-U.TSTA(R5) ; Is prompt output in progress? BNE 60$ ; If NE yes - go on ASSUME BF$NOR,0 CLR R3 ; This is normal output CLR U.TFOB(R4) ; Take the buffers from ; the class driver 60$: MOVB R3,3(R1) ; Set the buffer type TST (R1) ; Last buffer? BEQ 100$ ; If 0-YES, chain done, branch MOV (R1),R1 ; If not-get next buffer BR 60$ ; And repeate 100$: CLR U.TOP(R4) ; First buffer=0 CLR U.TOC(R4) ; Remaining bytes=0 BISB #UL.TDA,U.LINS-U.TSTA(R5) ; Set XMT-DATA-AVAIL DOFORK: CALL PRIFRK ; Do priority fork IODON: MOV (SP)+,R2 ; Registers MOV (SP)+,R1 ; And MTPS #TTPRI ; Raise to priority 5 SAVNR ; Save and restore R4 and R5 CALL TTSET1 ; Go put TT fork block on ; fork queue if needed MTPS #0 ; Back to zero RETURN ; ; Called by terminal driver on IO.KILL. All data in XMT buffers ; will be lost. LAT processor will be called to cancel all ; pending transmit and receive operations. ; LHABOX:: CALL CLEAN ; Clean up the buffers MOV #PO$ABO,R3 ; Param-abort output CALL LTPRC ; Call LAT process RETURN ; ; ; Terminal driver calls to do a time-out processing. ; This entry point will be called on IO.HNG or "BYE" command to ; disconnect link and logoff remote terminal. ; ; If and transmit data is still outstanding, the session is marked ; for hangup (HIP) in the status extension. The LAT process is then ; called to mark the session block disconnect in progress (DIP), the ; IO.HNG or IO.DET I/O packet is saved and a return is executed back ; to PPHNG in TTATT, which calls this routine. ; The terminal is disabled from receiving any new data I/O packets ; (US.DSB set). ; ; Once all the transmit data has been sent to the server, the session ; block is cleaned up, the session is disonnected, and the IO.HNG or ; IO.DET is finished ($IOFIN called). ; ; If this routine is called a 2nd time, for any reason, the session ; is unconditionaly disconnected. ; ; ; INPUTS: IF DF T$$OVL ; R5 - U.TSTA of terminal ; ; 6(SP) = IRP Address of IO.HNG or IO.DET ; 4(SP) = Return PC in PPHNG ; 2(SP) = KINAR5 or TTATT ; (SP) = Return PC in MPROT ; ; .IF NDF T$$OVL ; R5 - U.TSTA of terminal ; ; 2(SP) = IRP Address of IO.HNG or IO.DET ; (SP) = Return PC in TTATT ; LHMTIM:: BITB #UL.TDA,U.LINS-U.TSTA(R5) ; is there transmit data avail? BEQ 5$ ; if EQ - no, hang up line.. BITB #LE.HIP,U.CREN-U.TSTA(R5) ; Hangup In progress? BNE 5$ ; if NE - yes, hang it up! BISB #LE.HIP,U.CREN-U.TSTA(R5) ; show hangup in progress BISB #US.DSB,U.STS-U.TSTA(R5) ; Toggle read/write .IF DF T$$OVL MOV 6(SP),R0 ; Recover IRP address CLR 6(SP) ; Clear IRP address .IFF ;T$$OVL MOV 2(SP),R0 ; Recover IRP address CLR 2(SP) ; Clear IRP address .ENDC ;T$$OVL MOV #PO$MSD,R3 ; Function - Mark SES disconnect CALL LTPRC ; Call LAT process direct TST R0 ; Did LAT take I/O packet? BEQ 20$ ; if EQ, yes - Let LAT try to ; send remaining data before ; hanging up line .IF DF T$$OVL MOV R0,6(SP) ; Recover IRP address .IFF ;T$$OVL MOV R0,2(SP) ; Recover IRP address .ENDC ;T$$OVL BICB #LE.HIP,U.CREN-U.TSTA(R5) ; Clear Hangup in Progress ; 5$: MOV #PO$DSC,R3 ; Function code-disconnect line 7$: MOV R1,-(SP) ; Save R1 BICB #17,U.CREN-U.TSTA(R5) ; Clear credits field CALL LTPRC ; Call LAT process direct MOV R5,R1 ; R1-UCB address for $LHSTP CALL $LHSTP ; Stop line-will call MHUP ; And clear the line BIT #S6.LAT,U.TST6-U.TSTA(R5) ; Is this a Lat Application Term BEQ 10$ ; if not, just return MOV #-1,R3 ; Set up R3 for call CALL LHST1 ; Reset terminal... 10$: MOV (SP)+,R1 ; Restore register 20$: RETURN ; ; Line parameters have changed. Only flow control change information ; is processed for now. A buffer will be allocated and the info put ; in it. ; LHLPAR:: MOV R1,-(SP) BEQ 40$ ; If EQ, Nothing being changed MOV R0,-(SP) MOV R2,-(SP) CALL ALTB ; Allocate T$$BFL buffer BCS 30$ ; If CS, No buffer - report error ; Link word cleared in ALTB MOVB #BF$FLO,3(R2) ; Set the type MOVB R1,4(R2) ; Fill in the control flags MOV U.SCB-U.TSTA(R5),R0 ; Get SCB address MOVB S.KRB+6(R0),2(R2) ; Fill in the Data_b slot size MOV R5,R0 ; Compute address of buffer chain ADD #U.TRLH-U.TSTA,R0 ; ... 10$: TST (R0) ; Any link? (Also clear carry) BEQ 20$ ; If EQ, End of chain found MOV (R0),R0 ; Get next buffer in chain BR 10$ ; Loop till end of chain found 20$: MOV R2,(R0) ; New end of chain 30$: MOV (SP)+,R2 ; Restore registers MOV (SP)+,R0 ; ... MOV (SP)+,R1 ; ... ;**-1 RETURN ; Return 40$: ;SA498 MOV (SP)+,R1 ; Restore register ;SA498 CALLR YLLPAR ; Report error ;SA498 ; ; If CON ONL set the write disabled bit and let it rip. ; If CON OFF return an error so nobody can muck with our TT's. ; LHUONL:: BISB #US.DSB,U.STS-U.TSTA(R5) ; disable read/writes on TT RETURN LHUOFF:: MOVB #IE.DNR,$SCERR ; Return error code in $SCERR RETURN LHSTOX:: BIC #S2.CTS,-U.TSTA(R5) ; We can't be XOFFed from ; a server LHCOFF:: LHCONL:: LHCPUP:: LHUPUP:: LHPWUP:: LHRESX:: RETURN ; And exit PRIFRK: MOV R4,-(SP) ; Save R4 MOV #FR.LAT,R3 ; LAT fork mask bit set MTPS #TTPRI ; Raise to priority 5 CALL FORK ; Queue fork block (R4 altered) MTPS #0 ; Back to zero MOV (SP)+,R4 ; Restore R4 RETURN ; ; Data message received from server. Each UCB contains bias/virtual address ; of a slot header for that link. The slot header contains the slot data ; size byte. ; ; Look through UCB chain and send to TTDRV all slots where the "receive data ; available" bit is set. ; ; If a slot is done, then the data counter in the slot header will be 0 ; and the C.STS word in the CCB (number of slots in buffer) will be decremented ; by 1. ; ; If "RCV-STOPPED" state is set (TTDRV back-offed with XOFF because of ; resources allocation failure) data will not be copied from the slot. ; Check RSV-STOPPED on entry and after each ; return from ttdrv when outputting a character (ICHAR1 call). ; In this case data slot counter will contain number of characters left ; in slot, and U.RSDV will contain address (virtual) of the next byte ; to output. C.STS will not be decremented. ; ; Note: ; UL.RDA bit is set by lat process only for lines, that have information ; available for current operation. ; ; Input: ; None ; Output: ; R3-status: 0-success, <0-error ; R1,R2-Destroyed ; Other registers - preserved ; Usage: ; R5 - U.TSTA address of current UCB ; R2 - LH'S DCB address ; $LHINP:: CLR R3 ; Assume success CLR R2 ; First entry in DCB 10$: CALL FNDUCB ; Find next LH UCB TST R5 ; Next UCB found? BNE 20$ ; Branch if yes ; No more UCBS RETURN ; And exit 20$: ; R5-next (first) UCB'S U.TSTA BITB #UL.LEN,U.LINS-U.TSTA(R5) ; Link enable? BEQ 10$ ; No-get next UCB BITB #UL.RDA,U.LINS-U.TSTA(R5) ; Receive data available? BEQ 10$ ; No-get next UCB ; ; The following code can be used when the LAT architecture provides ; a way to send the XOFF charcter to stop the server from sending more ; data. Meanwhile, the LAT Process tests this bit, and will not extend ; any more credits to the server until it is cleared. Note - there is ; still room in the typeahead buffer for a few more characters! ; ; BITB #UL.RSS,U.LINS-U.TSTA(R5) ; RCV-STOPPED on that link? ; BEQ 25$ ; No-copy slot ; BR 10$ ; And get next UCB 25$: ; UCB found-prepare copy slot MOV R2,-(SP) ; Save DCB address MOV U.RBHA-U.TSTA(R5),R1 ; R1-slot header V.A. start ADD #SL$SBC,R1 ; R1-slot size byte virtual addr MOV R1,R4 ; Save it (needed later) MOV #-1,R2 ; R2<0 (get char. operation) CALL GCHR ; Returns R2-slot size on right CLR R0 ; Prepeare R0 BISB R2,R0 ; R0-slot size MOV U.RSDV-U.TSTA(R5),R1 ; R1-slot data virt. start 30$: ; Loop-move slot char. in loop MOV #-1,R2 ; R2<0 (get char. operation) CALL GCHR ; Get character (R2 on right) MOV R0,-(SP) ; Save registers MOV R1,-(SP) ; MOV R4,-(SP) ; MTPS #TTPRI ; Raise to priority 5 CALL ICHAR1 ; Move char. from R2 to TTDRV MTPS #0 ; Back to zero MOV (SP)+,R4 ; Restore registers MOV (SP)+,R1 ; MOV (SP)+,R0 ; INC R1 ; Point to next character BITB #UL.RSS,U.LINS-U.TSTA(R5) ; RCV-STOPPED on that link? BNE 40$ ; Yes-process it SOB R0,30$ ; Copy all characters 35$: MOV U.CCBA-U.TSTA(R5),R2 ; R2-CCB address CLR U.CCBA-U.TSTA(R5) ; Show slot done DEC C.STS(R2) ; Decrement slots counter BICB #UL.RDA,U.LINS-U.TSTA(R5) ; Clear receive data available ; ; When the entire slot has been processed do not update the slot counter. ; This is not necessary and it allows the LAT process to use one slot ; for multiple start session slots. ; BR 50$ ; Slot done-process it 40$: ; Slot done or stopped DEC R0 ; Was not decremented by SOB BEQ 35$ ; Branch if it is really done MOV R1,U.RSDV-U.TSTA(R5) ; Store current data virtual MOV R4,R1 ; Restore slot data counter addr MOV R0,R2 ; R2>=0-put operation CALL GCHR ; Put counter in slot header 50$: MOV (SP)+,R2 ; Restore DCB address CLR R3 ; Return status-success BR 10$ ; Get next UCB ;######################### ;update comments ; ; The port scans the UCB chain to find the corresponding UCB ; (session/server IDS) and fills the output buffer. The scan ; starts from the specified UCB (R1). ; ; After filling each slot the credits counter is decremented by 1. ; If the credits counter is 0, no information will be transferred ; to the output buffer for this particular link. ; ; Operation fills the output buffer according to next set of rules: ; - Go through all UCBs and fill all slots for UCBs with the ; UL.TDA bit set; ; - Stop when there is no more room in output buffer; ; - If there is room in the buffer after the path through all of ; the UCBs has been made and there is XMT-STOPPED links start ; again if there are any credits available; ; - the message is filled until the message maximum length is reached ; or until all of the data has been moved. ; ; Input: ; R1 - UCB address to start scanning or 0 (start from the beginning) ; R2 - Server number ; R4 - Address of CCB, containing: ; Buffer bias C.BUF ; Buffer virtual addr C.BUF+2 -After message header ; Buffer length C.CNT -Without MSG header ; Maximum slot length to fill out is in U.SLSZ ; ; Output: ; R1 - UCB address were scan was stopped ; R2 - Server number ; R3 - Status: 0-success, >0-number of links in XMT-STOPPED state, <0-error ; R4 - Address of CCB, containing: ; Buffer bias C.BUF ; Virtual end of data C.BUF+2 (next available byte) ; Remaining in buffer C.CNT ; ; ; Note: ; U.TRSC, U.TRSA and UL.TDA are cleared when all of the XMT chain ; has been copied into the output buffer and all XMT buffers deallocated. ; ; Note: ; Register 1 is used as a bit mask: ; - Bit 1 is set if R1, provided on call from LAT process ; contained address of the UCB in the middle of the UCB ; chain or terminal driver call LHSTAX from ODONE call. ; In that case we need to repeate loop once more. ; - Bit 2 is set if any of the links has a transmit credit. ; ; $LHOUT:: MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 CLR R3 ; Prepare XMT stopped counter CLR R2 ; Start from the beginning CALL FNDUCB ; Ret. DCB (R2) & 1-st UCB (R5) CMP R1,R5 ; LAT calls with 1-st UCB in R1? BNE 1$ ; Branch if not CLR R1 ; Yes-clear R1 bit mask BR 15$ ; And go to process first UCB 1$: ; Not 1-st UCB in R1 on call TST R1 ; LAT calls with 0 in R1? BEQ 15$ ; Yes-start proc. First UCB (R5) ; R1 not EQL 1-st UCB, and not 0 ; -LAT calls with UCB in the ; Middle of the UCB chain MOV R1,R5 ; In R5-UCB address to start MOV #1,R1 ; Set repetition bit mask BR 15$ ; And process that UCB 2$: ; Look through all UCB chain CLR R2 ; Start from first CLR R1 ; Clear bit mask 5$: ; Continue through UCBs CALL FNDUCB ; Next (first) UCB TST R5 ; All UCBs done? BNE 15$ ; No-continue processing UCBS ; All UCBs processed BIT #1,R1 ; Do we have request to repeat? BNE 2$ ; Yes-start from the beginning ; And clear all mask ; At least once we already ; Processed all UCBs TST R3 ; Any links have been stopped? BEQ 10$ ; No-all done, get out ; There are stopped links BIT #2,R1 ; Any link has a credit? BNE 2$ ; Yes-repeat from the beginning ; No-get out 10$: ; All done-went through all UCBS ; No XMT stopped links, or no ; More credits, or buffer is ; Full-return MOV (SP)+,R2 ; Restore MOV R5,R1 ; UCB address were scan stopped TST (SP)+ ; Registers RETURN ; And exit 15$: BITB #UL.LEN,U.LINS-U.TSTA(R5) ; Link enabled? BEQ 5$ ; No-get next link CMP (SP),U.SRVN-U.TSTA(R5) ; Requested circuit? BNE 5$ ; Not-get next link 14$: BITB #LE.HIP,U.CREN-U.TSTA(R5) ; hangup in progress? BEQ 114$ ; IF eq - normal output BITB #UL.TDA!UL.NTO,U.LINS-U.TSTA(R5) ; XMT data available? BNE 114$ ; if NE, something available BISB #LE.TDC,U.CREN-U.TSTA(R5) ; Set Transmit data completed BR 16$ ; Format STOP slot ; 114$: BITB #UL.TDA,U.LINS-U.TSTA(R5) ; XMT data available? BNE 16$ ; If set -check next condition ; UL.TDA not set BITB #UL.NTO,U.LINS-U.TSTA(R5) ; Did we have stalled ; non task output? BEQ 5$ ; No UL.TDA & no UL.NTO-next UCB ; Yes, we did, we did! CALL PRNTO ; Try to put it into output queue BITB #UL.TDA,U.LINS-U.TSTA(R5) ; Now is there any to output? BEQ 5$ ; If EQ no - next UCB ASSUME S2.CTS,100000 16$: ; ; The following lines of code have been commented out because the architecture ; doesn't allow flow control between server and host with characters, but ; instead uses credits to control the flow of data. Therefore, if we have the ; the credits, we will send the data. ; ; TST -U.TSTA(R5) ; XOFFED by user? ; BMI 5$ ; Yes-get next link ; ; Of course there is a buffer! (Used for debug only) ; TST C.BUF+2(R4) ; Check if output buffer addr 0 ; BEQ 5$ ; Yes-get next link ; Test for available credits ; Should always be the last test MOVB U.CREN-U.TSTA(R5),R0 ; Get credits BIC #177760,R0 ; * TSTB R0 ; any credits available? BLE 5$ ; No-get next link BIS #2,R1 ; Set bit mask-credits available ; UCB found (R5) ; BIT #1,C.BUF+2(R4) ; Slot on even boundary? BEQ 18$ ; Branch if yes INC C.BUF+2(R4) ; Make it even DEC C.CNT(R4) ; Decrement I/O buffer counter 18$: BITB #UL.TDA,U.LINS-U.TSTA(R5) ; Transmit data avail? BNE 119$ ; if NE, yes - go get it! ; Else must be completion ; of .HIP CMP C.CNT(R4),#SL$SDS ; I/O buff avail > slot header? BHI 19$ ; Branch if yes BISB #UL.TRS,U.LINS-U.TSTA(R5) ; Set transmitt stopped BR 10$ ; and exit ; 19$: BICB #LE.HIP,U.CREN-U.TSTA(R5) ; Clear hangup in progress BICB #17,U.CREN-U.TSTA(R5) ; Clear credits MOV R3,-(SP) ; Save R3 MOV R2,-(SP) ; Save R2 SUB #SL$SDS,C.CNT(R4) ; Subtract out slot header MOV C.BUF+2(R4),R2 ; Get slot header address ADD #SL$SDS,C.BUF+2(R4) ; Point at next avail. byte MOV #321,R3 ; Slot type, reason code DIAG CALL FILSH ; Fill in the slot header MOV (SP)+,R2 ; Restore R2 MOV (SP)+,R3 ; Restore R3 BR 5$ ; Go do next UCB 119$: ; Copy XMT chain in I/O buffer MOV R2,-(SP) ; Save DCB address MOV R3,-(SP) ; Save R3 (XMT-STOPPED counter) CLR -(SP) ; Initialize the slot type ; to zero which is for Data_a MOV C.BUF+2(R4),-(SP) ; Save start of the slot MOV U.TRLH-U.TSTA(R5),R2 ; R2-first buffer in XMT chain ; U.TRSC=0 if new XMT chain TST U.TRSC-U.TSTA(R5) ; All new XMT chain? BNE 20$ ; No-branch ; Yes, new chain MOVB 2(R2),U.TRSC-U.TSTA(R5) ; U.TRSC-bytes in first XMT buff 20$: CMP C.CNT(R4),#SL$SDS ; I/O buff avail > slot header? BHI 25$ ; Branch if yes ; I/O buff avail=-U.TSTA(R5) ; Make sure not XOFFed BISB #U2.RMT,U.CW2-U.TSTA(R5) ; Set line remote BIC #100000,6(R5) ; No autobaud detection BIT #S6.LAT,U.TST6-U.TSTA(R5) ; Lat Application Terminal? BEQ 10$ ; if EQ - no, call MANS CLR U.TST5-U.TSTA(R5) ; Reset U.TST5 CLRB U.TMTI-U.TSTA(R5) ; Clear modem timer BR 20$ ; Continue in common code.. ; 10$: MTPS #TTPRI ; Raise to priority 5 CALL MANS ; Answer the call-sets all ; Characteristics & line enable MTPS #0 ; Back to zero ; 20$: TST R3 ; Called from LHMTIM? BNE RET1 ; if NE - yes, just return BISB #UL.LEN,U.LINS-U.TSTA(R5) ; Show link enabled SEXIT: MOV (SP)+,R2 ; Restore R2 RET1: RETURN ; ; **-$LHTMO - A solicit has timed out ; ; This routine is called by LAT Process when a solicit has timed out. ; Any outstanding I/O is killed, and the current I/O is completed with ; Error status in R3 returned in the IOSB of the issuing task. ; ; INPUT: R1 - U.TSTA of terminal ; R2 - Error code ; ; OUTPUT: R1 - Unchanged ; R3 - 0 If success, <0 if error ; ; Other registers preserved ; $LHTMO::BIT #S6.LAT,U.TST6-U.TSTA(R1) ; Is this a L.A.T.? BEQ ERR1 ; If not, error! MOV R0,-(SP) ; Save R0 MOV R2,R0 ; Move error code SWAB R0 ; Get code to hi byte BISB #IE.DNR,R0 ; Get DNR to lo byte BR STP ; Finish I/O, clean up, etc ; ; ; The LAT process calls this entry point to stop a session. ; In R1 is the UCB address of the session to stop. ; ; Input: ; R1 - UCB address ; Output: ; R1 - Unchanged ; R3 - 0 if success, <0 if error ; R5 - modified ; ; Other registers preserved ; $LHSTP:: BITB #UL.LEN,U.LINS-U.TSTA(R1) ; Line enabled? BNE STP1 ; Branch if Yes ERR1: MOV #ER$SYN,R3 ; Synchr. error RETURN ; And return ; ; STP1: MOV R0,-(SP) ; Save R0 MOV #IE.DNR&377,R0 ; Return DNR error to task ; Save reg. destroyed by LHMHUP STP: MOV R1,R5 ; R5-UCB address MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 MOV R4,-(SP) ; Save R4 MOV R0,-(SP) ; Save status CALL MUCBX ; Map UCBX buffer (R4) CALL CLEAN ; Cleanup buffers BISB #US.DSB,U.STS-U.TSTA(R5) ; Toggle read/write CLRB U.LINS-U.TSTA(R5) ; Clear all link states MOV (SP)+,R0 ; Restore status MTPS #TTPRI ; Raise to priority 5 CALL LHMHUP ; Kill all I/Os and hang the line ; Clobbers R0,R1,R2,R3 MTPS #0 ; Back to zero CLR R3 ; Return success MOV (SP)+,R4 ; Restore MOV (SP)+,R2 ; Registers MOV (SP)+,R1 ; MOV (SP)+,R0 ; RETURN ; --* LHDET - Check to see if Lat Application Terminal session should be ; disconnected. ; ; ; A session is disconnected if the original connection to the ; application terminal at the terminal server was an implicit ; connection. Lat Process is mapped and called to check the ; status in the circuit block. ; ; Called by TTATT ; ; Inputs: R5 - U.TSTA of terminal ; ; Outputs: CS if terminal is to be hung up ; CC if not. ; LHDET:: BITB #LE.ORG,U.CREN-U.TSTA(R5) ; Session result of IO.ORG? BNE 10$ ; if NE yes, don't hang up TT BITB #LE.HIP,U.CREN-U.TSTA(R5) ; Hangup in progress? BNE 10$ ; if NE, yes - don't hang up. SEC ; show terminal to be hung up 10$: RETURN ; ; Common Subroutines ; ; FNDUCB-find next LH UCB ; Returns LH port first UCB and next/first UCB address. ; Input: ; R2-DCB address (0 if first entry) ; R5-Current UCB's U.TSTA address ; Output: ; R2=0 on input: ; R2-DCB address (0 if no LH CTB/DCB found) ; R5-First UCB's U.TSTA ; Carry set if no LH'S CTB/DCB found ; R2=DCB on input: ; R2-Unchanged ; R5-Next UCB's address (0 if no more UCBs) ; FNDUCB: TST R2 ; First entry? BNE 30$ ; Branch if not MOV $CTLST,R2 ; First CTB in chain 10$: CMP L.NAM(R2),#"LH ; TT device? BEQ 20$ ; BR if yes MOV (R2),R2 ; Next CTB BNE 10$ ; If NE, Check next one SEC ; CTB not found RETURN ; Return with no LH data base 20$: MOV L.DCB(R2),R2 ; R2-DCB address MOV D.UCB(R2),R5 ; R5-First UCB address ADD #U.TSTA,R5 ; R5-U.TSTA CLC ; CTB found RETURN ; R2-DCB, R5-First UCB 30$: CMPB U.SESN-U.TSTA(R5),D.UNIT+1(R2) ; Current unit-last? BLO 40$ ; BR if not CLR R5 ; No more units (return R5=0) BR 50$ ; And exit 40$: ADD D.UCBL(R2),R5 ; R5-Next unit 50$: RETURN ; And exit ; ; MOVSB - Move source buffer into output buffer ; Input: ; R0 - Number of bytes to copy ; R5 - UCB address, were: ; U.TRLH-U.TSTA - Source address ; U.TRSC-U.TSTA - Number of bytes left ; Send word in U.TRLH buffer-buffer size ; R4 - CCB address, containing output buffer bias/virt ; Output buffer should be biased through APR6. ; Output: ; C.BUF+2(R4) Modified - points to the first free byte in the output buff ; C.CNT(R4) Modified - remaining bytes in the output buffer ; ; Note: ; Algorithm works for I/D space and non-I/D space systems. KISARi, ; found for source buffer mapping always maps data space. ; ; All registers preserved ; MOVSB: MOV R0,-(SP) ; Save R0 MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 MOV R3,-(SP) ; Save R3 MOV R4,-(SP) ; Save R4 SUB R0,C.CNT(R4) ; C.CNT-Avail. in I/O buffer MOV U.TRLH-U.TSTA(R5),R2 ; R2-Source buffer address CLR R1 ; Settup for BISB BISB 2(R2),R1 ; R1-Number of bytes in buffer ADD #4,R2 ; R2-Bytes start in buffer ADD R1,R2 ; R2-End of buffer SUB U.TRSC-U.TSTA(R5),R2 ; R2-Current byte in buffer MOV R2,R1 ; R1-Source address ; Make R2 APR5 biased for BLXIO BIC #160000,R2 ; Clear APR number in R2 BIS #120000,R2 ; Make R2 APR-5 biased ; Set in R1 bias for BLXIO ASH #-12.,R1 ; R1-Real APR number*2 ; ASH may be used here (EIS) ; -we are using M-PLUS only BIC #177761,R1 ; Clear all junk bits MOV KISAR0(R1),R1 ; R1-Buffer bias MOV C.BUF(R4),R3 ; R3-Destination bias MOV C.BUF+2(R4),R4 ; R4-Destination address CALL $BLXIO ; Move data ; R0-Changed ; R2-Last source byte+1 ; R4-Last output byte+1 ; R1,R3-Preserved MOV R4,R1 ; Store R4 MOV (SP)+,R4 ; Restore CCB in R4 MOV R1,C.BUF+2(R4) ; New current V.A. in outp. buff MOV (SP)+,R3 ; Restore R3 MOV (SP)+,R2 ; Restore R2 MOV (SP)+,R1 ; Restore R1 MOV (SP)+,R0 ; Restore R0 RETURN ; ; MUCBX - Map UCBX buffer on call from LAT process ; ; Note: ; Need that only if UCBX is being used on calls from LAT process. ; ; Input: ; R5 - U.TSTA ; ; Output: ; None ; MUCBX: .IF DF T$$SPL ; I/D space systems MOV U.TAPR-U.TSTA(R5),@#KDSAR5 ; Map UCBX MOV #120000,R4 ; R4-Virtual UCBX address .IFF ;T$$SPL ; Non I/D space systems MOV U.TUX-U.TSTA(R5),R4 ; Get UCBX .ENDC ;T$$SPL RETURN ; ; PRNTO - Process non task output. ; ; Allocate buffers and move the output into the buffers ; updating U.TOC and U.TOP+2 in the process. ; ; Link these buffers to the end of the U.TRLH chain with the ; buffer type set to zero. (Not prompt or flow control info.) ; ; If enough buffers cannot be allocated exit with U.TOC and ; U.TOP+2 settup for the remainder. Else U.TOC will be zero. ; ; If the buffer resides in APR6, and U.TOP is non-zero, then ; insure that the external buffer is mapped to move data from ; one spot to the next. ; ; If any buffers were added to U.TRLH set UL.TDA. ; ; Input: ; R5-UCB address ; PRNTO: MOV R0,-(SP) ; MOV R1,-(SP) ; Save MOV R2,-(SP) ; Registers MOV R3,-(SP) ; MOV R4,-(SP) ; CALL MUCBX ; Returns UCBX addr in R4 TSTB U.TOC(R4) ; anything to do? BEQ 70$ ; if EQ, just return.. 5$: MOV U.TRLH-U.TSTA(R5),R1 ; R1-XMT buffers chain BEQ 30$ ; Branch if there is no chain 10$: TST (R1) ; There is a chain- BEQ 20$ ; Find end of MOV (R1),R1 ; Terminal buffers BR 10$ ; Chain ; R1-addr of the last buffer 20$: CMPB #BF$FLO,3(R1) ; Is this a Flow control buffer? BEQ 30$ ; If EQ yes - Don't put in data CMPB #T$$BFL-4,2(R1) ; Is this one full? BEQ 30$ ; If EQ yes - get new one 25$: MOV R1,R2 ; Settup register for call CALL MOVBFR ; Move the characters BR 50$ ; Check if done 30$: CALL ALTB ; Allocate T$$BFL buffer BCS 60$ ; Branch if alloc. failure ; Buffer allocated, R2=address ; Build dest. buff from source CLR (R2) ; Clear last buffer link pointer ASSUME BF$NOR,0 CLR 2(R2) ; Clear count and type CALL MOVBFR ; Move the characters TST R1 ; Is there a U.TRLH chain? BNE 45$ ; Yes-branch MOV R2,U.TRLH-U.TSTA(R5) ; No-new buffer-first one BR 50$ ; And out 45$: ; R1 points to last buffer MOV R2,(R1) ; Link buffer to U.TRLH chain 50$: TSTB U.TOC(R4) ; Did we do it all yet? BNE 5$ ; If NE no - Go on BR 70$ ; All done 60$: BISB #UL.NTO,U.LINS-U.TSTA(R5) ; Note waiting output 70$: MOV (SP)+,R4 ; Restore MOV (SP)+,R3 ; MOV (SP)+,R2 ; Registers MOV (SP)+,R1 ; MOV (SP)+,R0 ; RETURN ; And exit ; ; CLEAN - Cleanup after an abort or stop session ; ; Deallocate all buffers other than prompt buffers. Clear ; transmit data available flag. An IO.RPR buffer chain ; will be the last thing in the list except for a possible ; DATA_B buffer which will be deallocated along with the ; IO.RPR chain later. ; CLEAN: MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 MOV U.TRLH-U.TSTA(R5),R2 ; Get the listhead BEQ 30$ ; Branch if no buffers 10$: CMPB #BF$RPR,3(R2) ; Is this IO.RPR? BEQ 30$ ; If EQ yes - Don't deallocate MOV (R2),-(SP) ; Get the next buffer CALL DETB ; Delete this buffer MOV (SP)+,R2 ; Get the next buffer BNE 10$ ; And go on if there is one 30$: BICB #UL.TDA!UL.NOD,U.LINS-U.TSTA(R5) ; Clear the flag CLR U.TRLH-U.TSTA(R5) ; Clear XMT queue CLR U.TRSC-U.TSTA(R5) ; Clear queue counter MOV (SP)+,R2 MOV (SP)+,R1 RETURN ; And all done .PSECT MAP5 ;+ ; **-MOVBFR- Copy buffer data into TTDRV buffers, and link ; into the pending data chain ; ; Note: The buffer may need to be mapped, and therefore this ; code must reside in APR5 to work correctly. ; ; Move the data and update counts and pointers ; ; R2 - Buffer address ; MOVBFR: MOV R2,-(SP) ; Save R2 CLR -(SP) ; Prepare for BISB BISB 2(R2),(SP) ; Get current in buffer MOV (SP),-(SP) ; Duplicate top of stack MOV #T$$BFL-4,R0 ; Get buffer size SUB (SP),R0 ; get remaining space in buffer CLR R3 ; Prepare for the BISB BISB U.TOC(R4),R3 ; R3-string count CMPB R3,R0 ; Will it fit? BHI 20$ ; If HI no - Do one buffer MOV R3,R0 ; Move all of it 20$: SUB R0,R3 ; Compute the remaining MOVB R3,U.TOC(R4) ; And store it ADD R0,(SP) ; Add in these characters MOVB (SP)+,2(R2) ; Move byte counter in buffer MOV U.TOP+2(R4),R3 ; R3-source buffer start address ADD R0,U.TOP+2(R4) ; Update the source ADD #4,R2 ; Data start address in buffer ADD (SP)+,R2 ; Address in buffer for this data .IF DF,T$$ACD ; ACD support? BIT #S2.OBF,2(R5) ; Are we doing buffered output? BNE 60$ ; If NE, yes, buffer is in TTCOM TST U.TOP(R4) ; is a bias provided? BEQ 60$ ; if EQ, nope, no need to map CMP R3,#140000 ; is the buffer in APR6? BLO 60$ ; if LO, nope, no mapping MOV @#KISAR6,-(SP) ; save current mapping 40$: MOV U.TOP(R4),@#KISAR6 ; map the buffer if needed MOVB (R3)+,-(SP) ; copy the byte MOV 2(SP),@#KISAR6 ; remap TTCOM MOVB (SP)+,(R2)+ ; Move byte from echo buffer SOB R0,40$ ; until all done TST (SP)+ ; clean the stack BR 80$ ; skip the byte copy .IFTF ;DF,T$$ACD 60$: MOVB (R3)+,(R2)+ ; copy the character SOB R0,60$ ; Move all bytes .ENDC ;DF,T$$ACD 80$: ; reference label ; Destination buffer built BISB #UL.TDA,U.LINS-U.TSTA(R5) ; Data is now available MOV (SP)+,R2 ; Restore R2 RETURN ; ; FILSH - Fill in slot header session number and slot length bytes ; ; Input: ; R2 - Slot header address ; R3 - Slot type ; C.BUF+2(R4) - Next available byte in I/O buffer ; U.SESN - Slot number ; ; Output: ; Bytes filled in slot header ; FILSH: MOV R1,-(SP) ; Save R1 MOV C.BUF+2(R4),R1 ; R1-Next available byte SUB R2,R1 ; R1-Filled bytes in slot (+HDR) SUB #SL$SDS,R1 ; Filled bytes without header MOV @#KISAR6,-(SP) ; Save APR6 MOV C.BUF(R4),@#KISAR6 ; Map output buffer MOVB R1,SL$SBC(R2) ; Fill slot counter in header MOVB U.SESN-U.TSTA(R5),SL$SID(R2) ; Fill slot identifyer MOVB R3,SL$TYP(R2) ; Fill in the slot type CMPB #240,R3 ; Data_b slot? ;JEM001 BNE 10$ ;JEM001 MOVB #4,SL$SDS(R2) ; Control flag ;JEM001 10$: ;JEM001 MOV (SP)+,@#KISAR6 ; Restore mapping MOV (SP)+,R1 ; Restore R1 RETURN ; ; GCHR - Get/Put character from/into unmapped buffer ; ; Input: ; U.RSBB - Buffer bias ; R1 - Byte virtual address ; R2- ; <0 - Get character from buffer to R2 ; >=0 - Put character from R2 into buffer ; ; Output for R2<0 - low byte in R2 ; GCHR: MOV @#KISAR6,-(SP) ; Save APR 6 MOV U.RSBB-U.TSTA(R5),@#KISAR6 ; Map input buffer TST R2 ; Test R2 BGE 10$ ; Branch if >=0 CLR R2 ; Prepare R2 BISB (R1),R2 ; Move character in R2 BR 20$ ; Done 10$: MOVB R2,(R1) ; Move character from R2 20$: MOV (SP)+,@#KISAR6 ; Restore APR6 mapping RETURN ; ; Call to LAT process: (APR 5 always). ; ; Call to LAT process is being made using $MPPRO routine. ; Bias of the LAT process is stored in S.KRB+2 of the scb. ; Virtual address of LAT is stored in the S.KRB+4 of the SCB. ; FPLAT:: ; This entry included in FRKTB ; Table in TTDAT module ; ; Call from fork process comes here with: ; R4-UCBX address ; R5-UCB address ; MOV R3,-(SP) ; Save R3 BITB #UL.XON,U.LINS-U.TSTA(R5) ; Called for XON? BEQ 10$ ; If EQ no - go on MOV #PO$XON,R3 ; Set the function code BR CALLT ; Call LAT process 10$: MOV R0,-(SP) ; Save R0 BITB #UL.NTO,U.LINS-U.TSTA(R5) ; Non task output pending? BNE 40$ ; If NE yes - Don't call ODONE BIT #S5.RPO,U.TST5-U.TSTA(R5) ; Is prompt output in progress? BNE 40$ ; If NE yes - No ODONE call ; ; Find out how many data buffers we have. If it is too many don't call ODONE. ; CLR R0 ; Init the count MOV U.TRLH-U.TSTA(R5),R3 ; Get start of list BEQ 30$ ; Branch if no more list 20$: INC R0 ; Update the count MOV (R3),R3 ; Get the next buffer BNE 20$ ; Branch if there is one 30$: CMP R0,#MAXBUF ; Too many? BLOS 35$ ; If LOS no - Go on BISB #UL.NOD,U.LINS-U.TSTA(R5) ; Note no ODONE call BR 40$ ; And call LAT process 35$: BIC #S1.DSI,(R5) ; Clear it MTPS #TTPRI ; Raise to priority 5 CALL ODONE ; Process the request MTPS #0 ; Back to zero BIS #S1.DSI,(R5) ; Reset S1.DSI for other processes 40$: MOV (SP)+,R0 MOV #PO$OUT,R3 ; Set the function code BR CALLT ; Call LAT process ; ; Direct call if priority message has to go out. In this case ; LAT should not call $LHOUT. ; Input parametrs: ; R3-Operation code; ; R5-UCB address ; LTPRC:: MOV R3,-(SP) ; Save R3 CALLT: MOV R4,-(SP) ; Save R4 MOV U.SCB-U.TSTA(R5),R4 ; R4-SCB address MOV S.KRB+2(R4),-(SP) ; Bias MOV S.KRB+4(R4),-(SP) ; Virtual CALL $MPPRO ; Maps and calls LAT process ; Restores SP MOV (SP)+,R4 ; Restore R4 MOV (SP)+,R3 ; Restore R3 RETURN ; And exit ; ; The LAT process calls LAT port at common entry point ; with the function code in R3. ; $LHDEV:: ; LH port entry point CLR R4 ; Always controller zero! MTPS #TTPRI ; Raise to PR5 TTSET$ LH ; Map APR6 for termianl driver MTPS #0 ; Back to zero CALL LHDEV6 ; Go into the Map6 psect MTPS #TTPRI ; Raise again RETURN ; Exit through TTSET .PSECT MAP6 LHDEV6: CLR R2 ; No DCB address CALL FNDUCB ; Go get first UCB address MOV U.SCB-U.TSTA(R5),R5 ; Get SCB address MOV S.KRB+10(R5),R1 ; Get input parameters MOV S.KRB+12(R5),R2 ; ... MOV S.KRB+14(R5),R3 ; ... MOV S.KRB+16(R5),R4 ; ... MOV R5,-(SP) ; Save address of SCB CALL @LHDSP(R3) ; Call function MOV (SP)+,R0 ; Restore SCB address MOV R1,S.KRB+10(R0) ; Return function parameters MOV R2,S.KRB+12(R0) ; .... MOV R3,S.KRB+14(R0) ; ... MOV R4,S.KRB+16(R0) ; ... MOV R5,S.KRB+20(R0) ; ... RETURN .ENDC ;T$$LTH .END